#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initWin();
    //初始化 舵机控制
    pwm = PwmControl::instance();
    pwm->initPwm();
    // 初始化定时器，设置为 1000 毫秒（1 秒）触发一次
   timer = new QTimer(this);
   // 连接定时器的 timeout 信号到 updateTime 槽函数
   connect(timer, &QTimer::timeout, this, &MainWindow::updateTime);
   // 启动定时器
   timer->start(1000);
   // 初始更新一次时间，避免启动时显示默认值
   updateTime();


   // 连接按钮信号槽das
   connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::onConfirmClicked);
   connect(ui->pushButton_2, &QPushButton::clicked, this, &MainWindow::onCancelClicked);
    // 输入框按回车键时触发确认按钮点击事件
    connect(ui->lineEdit, &QLineEdit::returnPressed, ui->pushButton, &QPushButton::click);
    // 连接返回按钮（pushButton_3）的点击信号到窗口的close槽函数
    connect(ui->pushButton_3, &QPushButton::clicked, this, &MainWindow::close);
}

void MainWindow::updateTime()
{
    // 获取当前日期时间并更新标签文本
        QDateTime currentDateTime = QDateTime::currentDateTime();
        QString timeText = currentDateTime.toString("yyyy年MM月dd日 HH:mm:ss") + "           福州站";
        ui->label_4->setText(timeText);

        // 获取当前时间（精确到分钟）
        QTime currentTime = currentDateTime.time();
        currentTime.setHMS(currentTime.hour(), currentTime.minute(), 0); // 忽略秒数，精确到分钟对比

}
// 确认按钮点击事件
void MainWindow::onConfirmClicked()
{
    // 1. 检查套接字是否有效且已连接
       if (!tcpSocket || tcpSocket->state() != QAbstractSocket::ConnectedState) {
           showMessage("发送失败", "未连接到服务器，请重新连接！", QMessageBox::Warning);
           return;
       }
       // 2. 获取输入的身份证号码（假设输入框是 ui->lineEdit）
       QString idCard = ui->lineEdit->text().trimmed();
       if (idCard.isEmpty()) {
           showMessage("输入为空", "请输入身份证号码！", QMessageBox::Warning);
           return;
       }
       // 3. 封装 JSON 数据
      QJsonObject jsonObj;
      jsonObj["cmd"] = "REQUESTUSERTICKET";
      QJsonArray dataArray;
      QJsonObject dataObj;
      dataObj["card_id"] = idCard; // 填充身份证号
      dataArray.append(dataObj);   // 将对象添加到数组

      // 3. 将 data 数组添加到根对象
      jsonObj["data"] = dataArray;

      QByteArray data = QJsonDocument(jsonObj).toJson(QJsonDocument::Compact); // 转换为紧凑的 JSON 字符串

      // 4. 发送数据
     qint64 bytesSent = tcpSocket->write(data);
     if (bytesSent == -1) {
         showMessage("发送失败", "数据发送失败：" + tcpSocket->errorString(), QMessageBox::Critical);
     } else {
         qDebug() << "已发送请求数据：" << QString::fromUtf8(data) << "（" << bytesSent << "字节）";
         ui->lineEdit->clear();  // 清空输入框
     }
}

// 取消按钮点击事件
void MainWindow::onCancelClicked()
{
    ui->lineEdit->clear();
}
//读取可用数据
void MainWindow::onReadyRead()
{
    QByteArray data = tcpSocket->readAll();  // 读取所有可用数据
    if (!data.isEmpty()) {
        QString reply = QString::fromUtf8(data);  // 转换为字符串
        qDebug() << "收到服务器回复：" << reply;
        paraServerJson(reply);
    }

}



void MainWindow::paraServerJson(const QString &jsonStr)
{
    // 1. 转换为 QJsonDocument
       QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8());
       if (doc.isNull()) {
           qDebug() << "JSON 解析失败，无效格式";
           QMessageBox::warning(this, "解析错误", "服务器返回数据格式不正确");
           return;
       }

       // 2. 获取根对象
       QJsonObject rootObj = doc.object();

       // 3. 解析 cmd 字段（判断命令类型）
       QString cmd = rootObj["cmd"].toString();
       // 新增：如果 cmd 为 "user"，提示身份证输入错误
      if (cmd == "NO_SUCH_USER") {
          qDebug() << "身份证输入错误";
          showMessage("输入错误", "身份证号码输入错误，请重新输入！", QMessageBox::Warning);
          return;
      }
       if (cmd != "USERTICKET") {
           qDebug() << "未知命令：" << cmd;
           return;
       }


       // 4. 解析 data 数组（列车信息列表）
       QJsonArray dataArray = rootObj["data"].toArray();
       if (dataArray.isEmpty()) {
           qDebug() << "没有列车信息";
           return;
       }
       // 5. 核心：遍历所有车票，先判断出发地，再判断时间窗口
       bool hasValidTicket = false;  // 标记是否存在符合条件的车票
       QString validTicketInfo;      // 存储符合条件的车票信息（用于提示）
       double validTicketId;       //存储有效车票的 ticket_id

       foreach (const QJsonValue &val, dataArray) {
               if (!val.isObject()) continue;  // 跳过非对象数据，避免崩溃
               QJsonObject ticketObj = val.toObject();
               // 4.1 提取当前车票的关键信息
               double ticketId = ticketObj["ticket_id"].toDouble();
               QString userName = ticketObj["name"].toString();
               QString trainId = ticketObj["train_code"].toString();
               QString departTimeStr = ticketObj["depart_time"].toString();
               double money = ticketObj["money"].toDouble();
               QString departPoint = ticketObj["depart_point"].toString();

               if (departPoint != "福州站") {
                           qDebug() << "车票" << trainId << "出发地不符：" << departPoint;
                           continue;  // 出发地不是福州站，无需后续时间判断，直接检查下一张
                       }

               // 关键修改：用 QDateTime 解析带日期的完整时间
               QDateTime departDateTime = QDateTime::fromString(departTimeStr, "yyyy-MM-dd HH:mm:ss");
               // 兼容其他可能的格式（如不带秒的 "yyyy-MM-dd HH:mm"）
               if (!departDateTime.isValid()) {
                   departDateTime = QDateTime::fromString(departTimeStr, "yyyy-MM-dd HH:mm");
               }
               // 若仍解析失败，跳过当前车票
               if (!departDateTime.isValid()) {
                   qDebug() << "车票" << trainId << "时间格式错误：" << departTimeStr;
                   continue;
               }

               // 获取当前完整时间（包含日期，避免跨天判断错误）
               QDateTime currentDateTime = QDateTime::currentDateTime();

               // 计算时间差（单位：分钟）：当前时间 到 出发时间 的差值（正数=当前早于出发）
               qint64 timeDiffSec = currentDateTime.secsTo(departDateTime);
               int timeDiff = timeDiffSec / 60;  // 转换为分钟

               // 4.5 判断是否在检票窗口期（5~15分钟）
               if (timeDiff >= 0 && timeDiff <= 30) {
                   hasValidTicket = true;  // 标记存在有效车票
                   // 拼接有效车票信息（用于弹窗显示）
                   validTicketInfo = QString("id:%1\n乘客：%2\n列车：%3\n出发时间：%4\n票价：%5元")
                                     .arg(ticketId).arg(userName).arg(trainId).arg(departTimeStr).arg(money);
                   validTicketId = ticketId; // 记录有效车票的 ticket_id
                   break;  // 找到有效车票，停止后续遍历
               }
           }

           // 5. 根据结果执行操作（成功/失败）
           if (hasValidTicket) {
               // 检票成功：显示有效车票信息 + 发送 666 到服务端
               QMessageBox::information(this, "检票成功", "找到符合条件的车票！\n\n" + validTicketInfo);
                // 语音播报：检票成功请快速通过
               //pwm->enable();
//                pwm->setAngle(180);


               // 发送数据
               // 封装 JSON 数据
              QJsonObject jsonObj;
              jsonObj["cmd"] = "TICKETCHECK";
              QJsonArray dataArray;
              QJsonObject dataObj;
              dataObj["ticket_id"] = validTicketId; // 填充id
              dataArray.append(dataObj);   // 将对象添加到数组

              // 3. 将 data 数组添加到根对象
              jsonObj["data"] = dataArray;

              QByteArray data = QJsonDocument(jsonObj).toJson(QJsonDocument::Compact); // 转换为紧凑的 JSON 字符串
              // 打印 JSON 字符串（关键新增）
              qDebug() << "发送给服务端的 JSON 数据：" << QString::fromUtf8(data);

              qint64 bytesSent = tcpSocket->write(data);
              if (bytesSent == -1) {
                  showMessage("发送失败", "数据发送失败：" + tcpSocket->errorString(), QMessageBox::Critical);

              } else {
                  showMessage("发送成功", "请求数据已发送至服务器", QMessageBox::Information);
                  ui->lineEdit->clear();  // 清空输入框
              }
           } else {
               // 检票失败：所有车票都不在窗口期内
               QMessageBox::warning(this, "检票失败", "所有车票均不在检票窗口期内（需出发前5-15分钟）");
           }
}

// 显示消息框（封装美化）
void MainWindow::showMessage(const QString &title, const QString &text, QMessageBox::Icon icon)
{
    QMessageBox msgBox(this);
    msgBox.setWindowTitle(title);
    msgBox.setText(text);
    msgBox.setIcon(icon);
    msgBox.setStyleSheet(R"(
        QMessageBox {
            font: 12pt 'Ubuntu';
            background-color: #f5f5f7;
        }
        QPushButton {
            font: 12pt 'Ubuntu';
            padding: 5px 15px;
            border-radius: 4px;
            background-color: #4a90e2;
            color: white;
            border: none;
        }
        QPushButton:hover {
            background-color: #3a80d2;
        }
    )");
    msgBox.exec();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initWin()
{
    // setGeometry(x坐标, y坐标, 宽度, 高度)
    // 此处x、y设为0，让窗口占满屏幕；宽度480，高度272
    this->setGeometry(200,200,960, 554);
}

void MainWindow::setTcpSocket(QTcpSocket *socket)
{
    tcpSocket = socket;
        if (!tcpSocket) {
            qDebug() << "⚠️ 传入的套接字为空";
            return;
        }

        // 关联接收数据信号（服务器返回数据时触发）
        connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::onReadyRead);
        // 关联断开连接信号
        connect(tcpSocket, &QTcpSocket::disconnected, this, [=]() {
            qDebug() << "❌ 与服务器断开连接";
            showMessage("连接断开", "已与服务器断开连接，请重新连接！", QMessageBox::Warning);
        });

        // 关联发送完成信号（可选：确认数据已写入缓冲区）
        connect(tcpSocket, &QTcpSocket::bytesWritten, this, [=](qint64 bytes) {
            qDebug() << "数据已写入缓冲区（" << bytes << "字节）";
        });
}
